#include "01_TaskQueue.h"

using std::cout;
using std::endl;
using std::unique_lock;

TaskQueue::TaskQueue(size_t capacity)
    :_capacity(capacity)
{}

TaskQueue::~TaskQueue()
{}
    
void TaskQueue::TaskPush(const int& value)
{
    // 1: 先加锁（阻塞直到拿到锁）
    unique_lock<std::mutex> lock(_mutex);

    // 2：若条件不满足，自动释放锁并休眠
    // -- 条件变量 根据条件 判断是否加锁或解锁
    // -- 由 锁 阻塞 线程运行
    _notFull.wait(lock, [this]{return !full();});

    // 3：条件满足后，锁已自动持有
    _que.push(value);

    // 4: 锁满足后，通知可能等待的消费者
    _notEmpty.notify_one();
}
    
int TaskQueue::TaskPop()
{
    // 1: 先加锁（阻塞直到拿到锁）
    unique_lock<std::mutex> lock(_mutex);

    // 2：若条件不满足，自动释放锁并休眠
    _notEmpty.wait(lock, [this]{return !empty();});

    // 3：条件满足后，锁已自动持有
    int result = _que.front();
    _que.pop();
    cout << "result = " << result << '\n';

    // 4: 锁满足后，通知可能等待的生产者
    _notFull.notify_one();

    return result;
}
    
bool TaskQueue::empty()
{
    return _que.empty();
}

bool TaskQueue::full(){
    return _que.size() == _capacity;
}

